﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

/*********************************************************
 * 命名空间 Simple.Utils.JObject
 * 接口名称 SimpleJObject
 * 开发人员：zdm
 * 创建时间：2023/12/12 13:51:12
 * 描述说明：
 * 更改历史：
 * 
 * *******************************************************/
namespace Simple.Tools
{
	/// <summary>
	/// 
	/// </summary>
	public class SimpleJObject: ISimpleJobject
	{
		/// <summary>
		/// 
		/// </summary>
		public SimpleJObject() { }
		/// <summary>
		/// 取出json中名称对应的对象
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="json"></param>
		/// <param name="names"></param>
		/// <returns></returns>
		/// <exception cref="ArgumentNullException"></exception>
		public T GetValue<T>(string json, params string[] names)
		{
			if (SimpleCheck.IsNull(names))
			{
				throw new ArgumentNullException(nameof(names));
			}
			var jObject = JsonConvert.DeserializeObject<JObject>(json);
			return GetValue<T>(jObject,names);
		}
		/// <summary>
		/// 取出json 中对应名称的的值，如果有对象将会序列号成对象
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="jObject"></param>
		/// <param name="names"></param>
		/// <returns></returns>
		public T  GetValue<T>(JObject jObject,params string [] names)
		{
			var token=GetToken<T>(jObject,names);
			return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(token));
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="jObject"></param>
		/// <param name="type"></param>
		/// <param name="names"></param>
		/// <returns></returns>
		public object GetValue(JObject jObject,Type type, params string[] names)
		{
			var token = GetToken(jObject,type,names);
			return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(token),type);
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="token"></param>
		/// <param name="names"></param>
		/// <returns></returns>
		private JToken GetToken(JObject token,params string[] names)
		{
			if (names == null || token == null)
			{
				return null;
			}
		
			JToken targetToken = token;
			int i = 0;
			foreach (var name in names)
			{
			
				if (!string.IsNullOrEmpty(name) && token[name] != null)
				{
					if(i==0){
						targetToken = token[name];
					}
					else
					{
						targetToken=targetToken[name];
					}
					i++;
				}
				else
				{
					break;
				}
			}
			return targetToken;
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="token"></param>
		/// <param name="type"></param>
		/// <param name="names"></param>
		/// <returns></returns>
		private JToken GetToken(JObject token,Type type,params string[] names)
		{
			if (SimpleCheck.IsNullOrEmpty(names))
			{
				if (type.IsDefined(typeof(ConfigurationAttribute)))
				{
					ConfigurationAttribute cfg = type.GetCustomAttribute<ConfigurationAttribute>();
					if (!SimpleCheck.IsNull(cfg))
					{
						names=cfg.GetNames();
						if (SimpleCheck.IsNullOrEmpty(names))
						{
							names = new string[] { type.GetClassName()};
						}
					}
				}
			}
			return GetToken(token,names);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="token"></param>
		/// <param name="names"></param>
		/// <returns></returns>
		private JToken GetToken<T>(JObject token, params string[] names)
		{
			return GetToken(token,typeof(T),names);
		}
	}
}
